package javaagent.jdbc;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @author ：zzs
 * @version : 1.0
 * @date ：Created in 2022/3/12 19:41
 * @description：
 */
public class JdbcCollects {

    /**
     * Connection注册代理
     * @param connection
     */
    public static Connection proxyConnection(final Connection connection) {
        Object c = Proxy.newProxyInstance(JdbcCollects.class.getClassLoader()
                , new Class[]{Connection.class}, new ConnectionHandler(connection));
        return (Connection) c;
    }



    /**
     * prepareStatement注册代理
     * @param prepareStatement
     */
    public static PreparedStatement proxyPreparedStatement(final PreparedStatement prepareStatement, SqlInfo sqlInfo) {
        Object o = Proxy.newProxyInstance(JdbcCollects.class.getClassLoader(),
                new Class[]{PreparedStatement.class},
                new PrepareStatementHandler(prepareStatement, sqlInfo));
        return (PreparedStatement) o;
    }

    /**
     * 前置代理方法
     *
     * @param connection 连接对象
     * @param sql        sql语句 prepareStatement提供
     * @return
     */
    public static SqlInfo begin(Connection connection, String sql) {
        SqlInfo sqlInfo = new SqlInfo();
        sqlInfo.beginTime = System.currentTimeMillis();
        try {
            sqlInfo.jdbcUrl = connection.getMetaData().getURL();
            sqlInfo.dataBaseName = getDbName(sqlInfo.jdbcUrl);
            sqlInfo.sql = sql;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return sqlInfo;
    }

    public static void end(SqlInfo sqlInfo) {
        sqlInfo.time = System.currentTimeMillis() - sqlInfo.beginTime;
        System.out.println(sqlInfo);
    }

    public static void error(SqlInfo stat, Throwable throwable) {
        if (stat != null) {
            if (throwable instanceof InvocationTargetException) {
                stat.error = ((InvocationTargetException) throwable).getTargetException().getMessage();
            } else {
                stat.error = throwable.getMessage();
            }
        }
    }
    private static String getDbName(String url) {
        int index = url.indexOf("?"); //$NON-NLS-1$
        if (index != -1) {
            String paramString = url.substring(index + 1, url.length());
            url = url.substring(0, index);
        }
        String dbName = url.substring(url.lastIndexOf("/") + 1);
        return dbName;
    }
}
